/*
 * Copyright (c) 2023 Huawei Technologies Co., Ltd.
 * openUBMC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *         http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

#ifndef CHIP_H
#define CHIP_H

#include "internal/hasdef.h"
#include <mc/engine.h>
#include <memory>
#include <string>
#include <vector>

// 宏定义常量
#define CHIP_OP_TYPE_READ            0
#define CHIP_OP_TYPE_WRITE           1
#define PLUGIN_REQUEST_WRITE_OFFSET  0x1f
#define PLUGIN_REQUEST_READ_LENGTH   129
#define PLUGIN_REQUEST_READ_RETRY    10
#define PLUGIN_REQUEST_READ_SLEEP_MS 100

namespace dev {

class bus_base; // 前向声明

class MC_API chip_base {
public:
    chip_base();
    virtual ~chip_base();

    bool                       init(mc::mutable_dict& csr_object);
    void                       set_left_chip(std::shared_ptr<chip_base> left_chip);
    void                       set_left_bus(std::shared_ptr<bus_base> left_bus);
    void                       set_host_bus(std::shared_ptr<bus_base> host_bus);
    std::shared_ptr<chip_base> get_left_chip() const;
    std::shared_ptr<bus_base>  get_left_bus() const;
    std::shared_ptr<bus_base>  get_host_bus() const;

    // 以下函数是chip_base的内部函数的定义, 可由子类重写
    virtual int32_t chip_init();
    virtual int32_t chip_test(uint32_t* result);
    virtual int32_t chip_reset();
    virtual int32_t open_channel(std::shared_ptr<bus_base> bus);
    virtual int32_t output_to_input(ACCESS_DATA_S& output_data, ACCESS_DATA_S& input_data);

    // 以下函数是chip_base的外部接口的内部实现, 可由子类重写
    virtual int32_t bit_read(uint32_t offset, uint8_t length, uint32_t mask,
                              std::vector<uint8_t>& in_buffer, std::vector<uint8_t>& out_buffer,
                              std::string& error);
    virtual int32_t bit_write(uint32_t offset, uint8_t length, uint32_t mask,
                               const std::vector<uint8_t>& in_buffer,
                               std::vector<uint8_t>&       out_buffer,
                               std::string& error);
    virtual int32_t block_read(uint32_t offset, uint32_t length, std::vector<uint8_t>& in_buffer,
                                std::vector<uint8_t>& out_buffer, std::string& error);
    virtual int32_t block_write(uint32_t offset, const std::vector<uint8_t>& in_buffer,
                                 std::vector<uint8_t>& out_buffer, std::string& error);
    virtual int32_t block_write_read(uint32_t offset, const std::vector<uint8_t>& indata,
                                      uint32_t read_length, std::vector<uint8_t>& out_buffer,
                                      std::string& error);
    virtual int32_t combo_block_write_read(uint32_t                    write_offset,
                                            const std::vector<uint8_t>& write_buffer,
                                            uint32_t read_offset, uint32_t read_length,
                                            std::vector<uint8_t>& in_buffer,
                                            std::vector<uint8_t>& out_buffer,
                                            std::string& error);
    virtual int32_t plugin_request(const std::string& plugin_name, const std::string& plugin_cmd,
                                    const std::vector<uint8_t>& params,
                                    std::vector<uint8_t>&       out_buffer,
                                    std::string& error);

protected:
    // 以下函数是chip_base的接口的内部函数实现, 子类仅继承，不需要重写
    int32_t      output(ACCESS_DATA_S& data);
    int32_t      input(ACCESS_DATA_S& data);
    int32_t      data_access(uint32_t mask, uint32_t offset, uint32_t length,
                              const std::vector<uint8_t>& in_buffer, std::vector<uint8_t>& out_buffer,
                              uint8_t optype);
    ACCESS_DATA_S pack_access_data(uint32_t mask, uint32_t offset, uint32_t length,
                                   const std::vector<uint8_t>& in_buffer,
                                   std::vector<uint8_t>& out_buffer, uint8_t optype);

protected:
    // 基类对象属性
    uint32_t m_address;
    uint8_t  m_offset_width;
    uint8_t  m_address_width;
    uint32_t m_write_timeout;
    uint32_t m_read_timeout;
    uint8_t  m_rw_block_size;
    uint8_t  m_write_interval;
    uint8_t  m_read_interval;
    uint8_t  m_write_retry_times;
    uint8_t  m_read_retry_times;

    // 前级器件指针 - 使用shared_ptr管理生命周期
    std::shared_ptr<bus_base>  m_left_bus;
    std::shared_ptr<bus_base>  m_host_bus;
    std::shared_ptr<chip_base> m_left_chip;
};

} // namespace dev

#endif // CHIP_H
